home *** CD-ROM | disk | FTP | other *** search
- ==============================================================================
- BBS: -=- Edge of the Century -=-
- To: DANIEL KEMPTON Date: 01-20-93 (05:13)
- From: GREG VIGNEAULT Number: 3196 [140] Pascal
- Subj: CRITICAL ERROR HANDLER Status: Public
- ------------------------------------------------------------------------------
- DK> Can anyone PLEASE give me information on how to write a critical
- > error handler.
-
- Below is a quick'n-dirty critical error handler, written without
- any Asm (so is usable from TP v4.0+). To test it, put a write-
- protected diskette in drive A:, then run the program. It should
- report error #19 (13 hex, disk write-protected).
-
- It'll need to be modified & trimmed to your purpose. You might
- code your handler to simply ignore errors, then let your main
- program take appropriate action, depending on the error, etc.
-
- DOS functions $00..$0C, $30, and $59 should be safe calls from the
- handler. Function $59 will return the extended error information
- code that you'll need to check (eg. #32 = share violation), as well
- as other data - which you can read up on, in a Dos reference text.
-
- I've used one byte of the DOS intra-process communication area (at
- $40:$F0) to return the value needed to tell Dos what to do about
- the error, rather than juggle registers. This should be okay.
-
- This code is cramped, to fit into a single message ...
-
- {*******************************************************************}
- PROGRAM Example; { Critical Error Handler }
- USES Dos, { import MsDos, GetIntVec, SetIntVec, Registers }
- Crt; { import CheckBreak }
- VAR OldISR : POINTER; { to save original ISR ptr }
- Reg : Registers; { to access CPU registers }
- errNumber : WORD; { extended error code }
- errClass, { error class }
- errAction, { recommended action }
- errLocus : BYTE; { error locus }
- FileName : String[13]; { for ASCIIZ file name }
- {-------------------------------------------------------------------}
- PROCEDURE cErrorISR( AX,BX,CX,DX,SI,DI,DS,ES,BP : WORD); Interrupt;
- BEGIN { This is it! ... }
- InLine($FB); { STI (allow interrupts) }
- Reg.AX := $3000; MsDos(Reg); { fn: get Dos version }
- IF (Reg.AH < 3) THEN Reg.AL := 3 { if less than Dos 3+ :FAIL }
- ELSE BEGIN { else take a closer look.. }
- Reg.AH := $59; Reg.BX := 0; { fn: get extended info }
- MsDos( Reg ); { call Dos }
- errNumber := Reg.AX; { set|clear error number }
- errClass := Reg.BH; errAction := Reg.BL; errLocus := Reg.CH;
- WriteLn; Write( 'Critical error (#', errNumber, ') ' );
- REPEAT WriteLn; { loop for user response }
- Write( 'Abort, Retry, Ignore, Fail (A|R|I|F) ? ',#7);
- Reg.AH := 1; MsDos(Reg); { get user input, via Dos }
- UNTIL UpCase(CHR(Reg.AL)) IN ['A','R','I','F'];
- CASE CHR(Reg.AL) OF { ... depending on input }
- 'i','I' : Reg.AL := 0; { = ignore error }
- 'r','R' : Reg.AL := 1; { = retry the action }
- 'a','A' : Reg.AL := 2; { = abort }
- 'f','F' : Reg.AL := 3; { = fail }
- END; {case}
- END; {if Reg.AH}
- Mem[$40:$F0] := Reg.AL; { to tell Dos what to think }
- InLine( $8B/$E5/ { mov sp,bp }
- $5D/$07/$1F/$5F/$5E/ { pop bp,es,ds,di,si }
- $5A/$59/$5B/$58/ { pop dx,cx,bx,ax }
- $06/ { push es }
- $2B/$C0/ { sub ax,ax }
- $8E/$C0/ { mov es,ax }
- $26/$A0/$F0/$04/ { mov al,es:[4F0h] }
- $07/ { pop es }
- $CF); { iret }
- END {cErrorISR};
- {-------------------------------------------------------------------}
- BEGIN { the main program... }
- CheckBreak := FALSE; { don't allow Ctrl-Break! }
- errNumber := 0; { clear the error code }
- GetIntVec( $24, OldISR ); { save current ISR vector }
- SetIntVec( $24, @cErrorISR ); { set our ISR }
- {===========================================================}
- { insert your test code here ... }
- FileName := 'A:TEST.TXT' + CHR(0); { ASCIIZ file name }
- Reg.DS := SEG( FileName ); { file name segment }
- Reg.DX := OFS( FileName[1] ); { file name offset }
- Reg.CX := 0; { normal attribute }
- Reg.AH := $3C; { fn: create file }
- MsDos( Reg ); { via Dos }
- {===========================================================}
- IF (errNumber <> 0) THEN BEGIN
- Write(#13#10#10,'For error #',errNumber,', user requested ');
- CASE Mem[$40:$F0] OF
- 0 : WriteLn('IGNORE'); { just your imagination }
- 1 : WriteLn('RETRY'); { ... endless futility ? }
- 2 : WriteLn('ABORT'); { DOS won't come back here! }
- 3 : WriteLn('FAIL'); { call technical support }
- END; {case}
- END; {if errNumber<>0}
- SetIntVec( $24, OldISR ); { must restore original ISR }
- END.
- {*******************************************************************}
-
- Greg_
-
- Jan.20.1993.Toronto.Canada. greg.vigneault@bville.gts.org
- ---
- * Baudeville BBS Toronto CANADA 416-283-0114 2200+ confs
- * PostLink(tm) v1.04 BAUDEVILLE (#1412) : RelayNet(tm)